﻿using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using PhotoGallery.Models;
using PhotoGallery.Repositories;
using System;
using System.Net;
using System.Linq;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using PhotoGallery.Utils.Authentication.JwtBearer;
using Swashbuckle.AspNetCore.Swagger;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
using PhotoGallery.Utils;

namespace PhotoGallery
{
    public class Startup
    {
        /// <summary>
        /// 是否启用CND
        ///* 不启用原因可能是流量不够了
        /// </summary>
        public static bool EnableCDN = true;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //TODO:实现开关CDN功能
            Boolean.TryParse(configuration["Site:enableCDN"], out EnableCDN);
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()            
                .Build();

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var connStr = Configuration["ConnectionStrings:Sqlite"];
            var admins = Configuration["Site:adminList"];
            if (!string.IsNullOrEmpty(admins))
            {
                var adminList = admins.Split(',', StringSplitOptions.RemoveEmptyEntries);
                services.AddSingleton<RoleModel>(new RoleModel(adminList));
            }
            
            services.AddSingleton<IPathProvider, PathProvider>();
            services.AddMvc();
            services.AddDbContext<PhotoGalleryRepository>(opts =>
            {
                opts.UseSqlite(connStr);
            });
            //services.AddSingleton<AlbumCollection>();
            services.AddSingleton<ImageProcessor>();
            var authsvc = services.AddAuthentication(options =>
             {
                 options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                 options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

             })
             .AddCookie(cfg => cfg.SlidingExpiration = true)
             .AddJwtBearer(cfg =>
             {
                 cfg.RequireHttpsMetadata = false;
                 cfg.SaveToken = true;

                 cfg.TokenValidationParameters = new TokenValidationParameters()
                 {
                     ValidIssuer = Configuration["JwtBearer:Issuer"],
                     ValidAudience = Configuration["JwtBearer:Audience"],
                     ClockSkew = TimeSpan.FromMinutes(5),//允许服务器与客户端之间时钟差
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtBearer:SecurityKey"]))
                 };
             });

            services.AddWebOptimizer(pipeline =>
            {
                //pipeline.MinifyJsFiles();
                pipeline.CompileScssFiles();
            });

            //Swagger - Enable this line and the related lines in Configure method to enable swagger UI
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info { Title = "PhotoGallery API", Description = "相册公开API接口", Version = "v1" });
                options.DescribeAllEnumsAsStrings();
                options.DocInclusionPredicate((docName, description) => true);
                // options.DocumentFilter<PhotoGallery.API.PhotoGalleryController>(); //定义controller名称
            });
            services.ConfigureSwaggerGen(c =>
            {
                var xmlFilePaths = new List<string>() {
                    "PhotoGallery.xml"
                    
                    //添加自己需要显示注释的的XML
                };
                foreach (var filePath in xmlFilePaths)
                {
                    var xmlFilePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, filePath);
                    if (File.Exists(xmlFilePath))
                    {
                        c.IncludeXmlComments(xmlFilePath);
                    }
                }
            });
            //缓存
            services.AddMemoryCache(opt => opt.ExpirationScanFrequency = TimeSpan.FromHours(3));

            
            //InitializeAlbumsCollection(services);

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                //app.UseHsts();
            }
            //nginx 前置代理
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor
                | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto
            });
            app.UseStatusCodePages("text/plain", "Status code page, status code: {0}");
            // app.UseDeveloperExceptionPage();

            app.UseAuthentication();

            app.UseWebOptimizer();

            app.UseStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = (context) =>
                {
                    var headers = context.Context.Response.GetTypedHeaders();
                    headers.CacheControl = new CacheControlHeaderValue()
                    {
                        MaxAge = TimeSpan.FromDays(365)
                    };
                }
            });


            //添加JWTBear
            app.UseJwtTokenMiddleware();

            app.UseSwagger();
            //app.UseSwaggerUI(c =>
            //{
            //    c.SwaggerEndpoint("/swagger/v1/swagger.json", "PhotoGallery API V1");
            //});
            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
            app.UseHSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "PhotoGallery API V1");
                options.InjectOnCompleteJavaScript("lang/zh-cn.js");  //语言文件
                options.InjectOnCompleteJavaScript("js/translator.js"); //语言切换    

            }); //URL: /swagger

            //app.UseHttpsRedirection();
            //app.UseCookiePolicy();
            app.UseMvc(routeBuilder => Routing.ConfigureRoutes(routeBuilder));

        }



    }
}
